home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_10 / 2n10062a < prev    next >
Text File  |  1991-07-15  |  17KB  |  617 lines

  1. COMMENT ~
  2. ---------------------------------------------------------
  3.                         LISTING 1
  4.  File:  breakout.asm
  5.  
  6.  This module contains routines necessary to enable
  7.  Ctrl-Break to "break out" of infinite loops.  A user
  8.  supplied clean up routine may be specified if necessary.
  9.  
  10.  MASM 5.1/TASM 2.0 - C callable installation &
  11.  de-installation functions.
  12.  
  13.  Language & memory model independant.  Change the .model
  14.  directive as needed.
  15.  
  16.  Author:  David Burki
  17. ---------------------------------------------------------
  18. END OF COMMENT ~
  19.  
  20. title BREAKOUT.ASM
  21. page 57,132
  22.  
  23. %  .model m_model, lang
  24.  
  25. ; ----  MACROS and EQUATES  ----
  26.  
  27. ;macro to simulate an interrupt so the interrupt returns
  28. ;to the instruction immediately following the call
  29. sim_int macro  num
  30.         pushf
  31.         call    cs:orig_&num
  32. endm
  33.  
  34. ;macro to push selected registers
  35. apush macro   a,b,c,d,e,f,g,h
  36.    irp x,<a,b,c,d,e,f,g,h>
  37.       ifnb <x>
  38.          push    x
  39.       endif
  40.    endm
  41. endm
  42.  
  43. ;macro to pop selected registers
  44. apop macro   a,b,c,d,e,f,g,h
  45.    irp x,<h,g,f,e,d,c,b,a>
  46.       ifnb <x>
  47.          pop     x
  48.       endif
  49.    endm
  50. endm
  51.  
  52. ;macro to install a replacement vector
  53. ;  --  assumes that ds = code seg of replacing function
  54. ;  --  all var names used to save original vector must be
  55. ;        2 characters long plus a training "h" (i.e. for
  56. ;        int 8h "orig_08h")
  57. install_vector macro vector_num,function_name
  58.         mov     ax,35&vector_num
  59.         int     21h
  60.         mov     word ptr orig_&vector_num,bx
  61.         mov     word ptr orig_&vector_num+2,es
  62.         lea     dx,function_name
  63.         mov     ax,25&vector_num
  64.         int     21h
  65. endm
  66.  
  67. ;macro to un-install a replaced vector
  68. ;  --  all var names used to save original vector must be
  69. ;        2 characters long plus a training "h" (i.e. for
  70. ;        int 8h "orig_08h")
  71. restore_vector macro replaced_vector
  72.         lds     dx,cs:orig_&replaced_vector
  73.         mov     ax,25&replaced_vector
  74.         int     21h
  75. endm
  76.  
  77. ; segment and offset of the BIOS break flag
  78. BIOS_SEG        equ     40h
  79. BREAK_FLAG_OFF  equ     71h
  80.  
  81. ; ----  CODE  ----
  82. .code
  83.  
  84. ; declare externally visible functions
  85. public  insure, cancel
  86.  
  87. ; NOTE:  all variables used here are part of the code
  88. ;        segment so the interrupt routines can have easy
  89. ;        access to them
  90.  
  91. ; --- storage for the address of the InDOS flag
  92. indos_addr              dd      0
  93.  
  94. ; --- storage for the address of the critical error flag
  95. critter_addr            dd      0
  96.  
  97. ; --- storage for the version of dos
  98. dos_major_version       db      0
  99. dos_minor_version       db      0
  100.  
  101. ; --- flag indicating disk i/o in progress
  102. busy_flag               db      0
  103.  
  104. ; --- far pointer to clean up routine
  105. exit_routine            dd      0
  106.  
  107. ; --- storage for original addresses of intercepted
  108. ;     interrupt vectors.
  109. orig_08h                dd      0
  110. orig_1bh                dd      0
  111. orig_13h                dd      0
  112. orig_25h                dd      0
  113. orig_26h                dd      0
  114.  
  115. ; --- storage for the segment addr of the psp of process
  116. ;     that asked for insurance  -  if zero, insurance isn't
  117. ;     in effect
  118. insured_psp     dw      0
  119.  
  120. ; --- flag if still processing in int 8h
  121. in_already      db      0
  122.  
  123. ; --- interrupted program's SS & SP
  124. save_ss         dw      0
  125. save_sp         dw      0
  126.  
  127. ; --- original C stack segment
  128. installer_ss    dw      0
  129. installer_sp    dw      0
  130.  
  131. ; --- local stack while in int_8h_handler
  132. my_stack        dw      256 dup(0)
  133. stack_top       label word
  134.  
  135.  
  136. assume ds:@curseg, es:nothing
  137.  
  138. ;---------------------------------------------------------
  139. ;  GET_DOS_VERSION()
  140. ; Obtain the version & revision of DOS.  Store the version
  141. ; in the variable "dos_major_version" and the revision in
  142. ; the variable "dos_minor_version".  Both variables are code
  143. ; segment variables.
  144. ;
  145. ; Returns:
  146. ;       AL - dos minor version number
  147. ;       AH - dos major version number
  148. ;---------------------------------------------------------
  149. public get_dos_version
  150. get_dos_version proc
  151.         mov     ah,30h
  152.         int     21h
  153.         mov     cs:dos_major_version,al
  154.         mov     cs:dos_minor_version,ah
  155.         ret
  156. get_dos_version endp
  157.  
  158. ;---------------------------------------------------------
  159. ;  GET_CRITICAL_ERROR_ADDR()
  160. ; This function obtains & saves the address of the
  161. ; critical error flag.  For DOS versions 3+, the critical
  162. ; error flag is the byte just before the InDOS flag. For
  163. ; DOS 2.x, it's the byte just after.
  164. ;
  165. ; NOTE:  get_dos_version() must be called before this
  166. ;        function
  167. ;
  168. ; NOTE:  For COMPAQ DOS version 3.x, the critical error
  169. ;        flag is located 01aah bytes BEFORE the InDOS flag.
  170. ;
  171. ; Trashes: AX
  172. ;---------------------------------------------------------
  173. public get_critical_error_addr
  174. get_critical_error_addr proc    USES ES BX
  175. ; --- get the address of the InDOS flag
  176.         mov     ah,34h
  177.         int     21h
  178.  
  179. ; --- dos 3.x or better use byte before InDOS
  180.         cmp     byte ptr cs:dos_major_version,3
  181.         jge     byte_before  ;good_version
  182.  
  183. ; --- dos 2.x, use byte after InDOS flag
  184.         inc     bx
  185.         jmp     store_critter_addr
  186.  
  187. byte_before:
  188.         dec     bx
  189.  
  190. store_critter_addr:
  191. ; --- save the address & return success
  192.         mov     word ptr cs:critter_addr,bx
  193.         mov     word ptr cs:critter_addr+2,es
  194.  
  195.         ret
  196. get_critical_error_addr endp
  197.  
  198. ;---------------------------------------------------------
  199. ;  GET_INDOS_ADDR()
  200. ; Uses the undocumented (but well known) function 34h of
  201. ; INT 21h to obtain a far pointer to the "InDOS" flag.
  202. ; Stores the address of the flag in the code segment
  203. ; variable "indos_addr".
  204. ;
  205. ; Trashes AX
  206. ;---------------------------------------------------------
  207. public get_indos_addr
  208. get_indos_addr proc     USES ES BX
  209. ; --- get the address
  210.         mov     ah,34h
  211.         int     21h
  212.  
  213. ; --- save address in cs referenced variable
  214.         mov     word ptr cs:indos_addr,bx
  215.         mov     word ptr cs:indos_addr+2,es
  216.         ret
  217. get_indos_addr endp
  218.  
  219. ;---------------------------------------------------------
  220. ;  CHECK_CRITTER_FLAG()
  221. ; Examine the undocumented "critical error" flag to
  222. ; determine if a critical error is in progress.
  223. ;
  224. ; Returns:
  225. ;     carry clear - A critical error is NOT in progress
  226. ;     carry set   - A critical error is in progress
  227. ;---------------------------------------------------------
  228. public check_critter_flag
  229. check_critter_flag proc USES AX DS SI
  230. ; --- ds:si <- address of critter flag
  231.         lds     si,dword ptr cs:critter_addr
  232.  
  233. ; --- check critter flag = zero
  234.         lodsb
  235.         or      al,al
  236.         jz      no_critter
  237.  
  238. ; --- critter flag not zero, return carry set
  239.         stc
  240.         jmp     critter_exit
  241.  
  242. ; --- critter flag zero, return carry clear
  243. no_critter:
  244.         clc
  245.  
  246. critter_exit:
  247.         ret
  248. check_critter_flag endp
  249.  
  250. ;---------------------------------------------------------
  251. ;  CHECK_INDOS_FLAG()
  252. ; Examine the undocumented "InDOS" flag to determine if
  253. ; non-rentrant DOS functions are currently executing.
  254. ;
  255. ; Returns:
  256. ;     carry clear - InDOS flag is zero.
  257. ;     carry set   - InDOS flag is non-zero.
  258. ;---------------------------------------------------------
  259. public check_indos_flag
  260. check_indos_flag proc   USES AX DS SI
  261. ; --- ds:si <-- addr of InDOS flag, then load al with
  262. ;     the byte at that address
  263.         lds     si,dword ptr cs:indos_addr
  264.         lodsb
  265.  
  266. ; --- indos flag equal zero, DOS is stable
  267.         or      al,al
  268.         jz      dos_stable
  269.  
  270. ; --- no, set carry & return
  271.         stc
  272.         jmp     indos_exit
  273.  
  274. ; --- yes, clear carry and return
  275. dos_stable:
  276.         clc
  277.  
  278. indos_exit:
  279.         ret
  280. check_indos_flag endp
  281.  
  282.  
  283. ;---------------------------------------------------------
  284. ;  CHECK_BREAK_BIT()
  285. ;   This function examines the BIOS Break Flag (bit 7 of
  286. ;   the byte at 40:71).
  287. ;
  288. ; Returns:
  289. ;     carry clear - Break Flag is clear.
  290. ;     carry set   - Break Flag is set.
  291. ;---------------------------------------------------------
  292. check_break_bit